/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logica;

import cern.jet.random.Poisson;
import cern.jet.random.engine.DRand;
import cern.jet.random.engine.RandomEngine;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

/**
 *
 * @author Jorge Maldonado
 */
public class principal implements Runnable {

    private int cantidadServidores, tamCola;
    private double tiempoServicio, tasaLlegada;
    private ArrayList<servicio> servidores;
    public ArrayList<persona> cola;
    private Thread ingreso, atencion;
    private boolean tamInfinito, vivo;
    private RandomEngine engine;
    private Poisson poisson;
    private javax.swing.JPanel panel, panel2,panel3,panel4;
    private ArrayList<datos_servicio> tasas;
    
    public principal(int cantidadServidores, int tamCola, ArrayList tiempoServicio, double tasaLlegada) {
        this.cantidadServidores = cantidadServidores;
        this.tamCola = tamCola;
        this.tasas = tiempoServicio;
        this.tasaLlegada = tasaLlegada;
        general.limiteFila = new Semaphore(tamCola, true);//10
        general.todos = new ArrayList();
        cola = new ArrayList();
        servidores = new ArrayList();
        


    }

    public principal(int cantidadServidores, ArrayList tiempoServicio, double tasaLlegada) {
        tamInfinito = true;
        this.cantidadServidores = cantidadServidores;
        this.tasas = tiempoServicio;
        this.tasaLlegada = tasaLlegada;
        general.limiteFila = new Semaphore(tamCola, true);//10
        general.todos = new ArrayList();
        cola = new ArrayList();
        servidores = new ArrayList();

    }

    public void setPanel(javax.swing.JPanel panel) {
        this.panel = panel;
    }

    public void setPanel2(javax.swing.JPanel panel) {
        this.panel2 = panel;
    }

    public void setPanel3(javax.swing.JPanel panel) {
        this.panel3= panel;
    }
    public void setPanel4(javax.swing.JPanel panel) {
        this.panel4= panel;
    }
    private void inicializarServidores() {
        servicio aux;
        datos_servicio tmp;
        for (int i = 0; i < cantidadServidores; i++) {
            tmp=tasas.get(i);
            aux=new servicio(tmp.velocidad, getCola(),tmp.nombre);
            panel2.add(aux);
            aux.setPanel(panel3);
            aux.setPanel2(panel4);
            getServidores().add(aux);
        }
    }
    /*necesita que se le  den dimencionales como segundos por persona*/

    private double Poisson() {
        return poisson.nextDouble();
    }

    public void inicializarProcesos() {
        general.hilos = new ArrayList();
        vivo = true;
        engine = new DRand();
        poisson = new Poisson(1 / tasaLlegada, engine);//6
        general.servicio = new Semaphore(cantidadServidores, true);//2
        general.hay_gente = new Semaphore(0, true);
        general.exc_mut = new Semaphore(1, true);
        inicializarServidores();
        general.hilos.add(ingreso);
        ingreso = new Thread(this);
        ingreso.start();
    }

    public void run() {
        double tiempo;
        double cont = 0;
        persona aux;
        while (vivo) {

            try {
                if (!tamInfinito)//se valida si el modelo no es con fila finita
                {
                    general.limiteFila.acquire();
                }
                tiempo = Poisson();
                System.out.println(tiempo);
                while (cont < tiempo) {
                    cont++;
                    Thread.sleep(general.velocidad);
                    while(logica.general.pausa){
                    Thread.sleep(100);
                }
                }
                general.exc_mut.acquire();
                aux = new persona();
                panel.add(aux);
                getCola().add(aux);
                general.exc_mut.release();
                general.hay_gente.release();
                cont = 0;
                while(logica.general.pausa){
                    Thread.sleep(100);
                }

            } catch (InterruptedException ev) {
            }
        }
    }
    

    public void matar() {
        vivo = false;
        general.velocidad=1000000;
    }

    /**
     * @return the cola
     */
    public ArrayList<persona> getCola() {
        return cola;
    }

    /**
     * @return the servidores
     */
    public ArrayList<servicio> getServidores() {
        return servidores;
    }
}
